#pragma once
#ifndef __G_RW_LOCK_H__
#define __G_RW_LOCK_H__

#include "GThread.h"
#include "GCounter.h"
#include "GSynchronizer.h"

namespace GThread
{

	class GConditionVar;

	class GRWLock
	{
	typedef GUtil::GAtomicCounter<GUInt32>	CounterType;

	private:
		void*			Lock;

		CounterType		ReadLocks;
		CounterType		ReadFrees;

		CounterType		WriteLocks;
		CounterType		WriteFrees;

		void			CheckLockFreeCount();

	public:
						GRWLock();
						~GRWLock();

		void			FreeRead();
		void			FreeWrite();

		void			AcquireRead();
		void			AcquireWrite();

		bool			TryAcquireRead();
		bool			TryAcquireWrite();

		bool			WaitRead(GConditionVar* CondVar, GUInt32 TimeOut = G_TIMEOUT_INFINITE);
		bool			WaitWrite(GConditionVar* CondVar, GUInt32 TimeOut = G_TIMEOUT_INFINITE);

		bool			IsCreated() const;

		bool			Create();
		void			Release();

	};
}

#endif